package com.example.video.common.security;

import com.example.video.common.security.handler.JsonAccessDeniedHandler;
import com.example.video.common.security.handler.JsonAuthenticationEntryPoint;
import com.example.video.common.security.handler.JsonAuthenticationFailureHandler;
import com.example.video.common.security.handler.JsonAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;


/**
 * @author : yj
 */
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private JsonAuthenticationFailureHandler failureHandler;

    private JsonAuthenticationSuccessHandler successHandler;

    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    private JsonAuthenticationEntryPoint entryPoint;

    private JsonAccessDeniedHandler jsonAccessDeniedHandler;

    @Autowired
    public void WebSecurityConfig(JsonAuthenticationFailureHandler failureHandler,
                                  JsonAuthenticationSuccessHandler successHandler,
                                  JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter,
                                  JsonAuthenticationEntryPoint entryPoint,
                                  JsonAccessDeniedHandler jsonAccessDeniedHandler){
        this.failureHandler = failureHandler;
        this.successHandler = successHandler;
        this.jwtAuthenticationTokenFilter = jwtAuthenticationTokenFilter;
        this.entryPoint = entryPoint;
        this.jsonAccessDeniedHandler = jsonAccessDeniedHandler;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new PasswordEncoder() {
            @Override
            public String encode(CharSequence rawPassword) {
                return rawPassword.toString();
            }

            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {
                return rawPassword.equals(encodedPassword);
            }
        };
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors().and()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)//禁用session
                .and()
                .exceptionHandling().accessDeniedHandler(jsonAccessDeniedHandler).authenticationEntryPoint(entryPoint)
                .and()
                .authorizeRequests()
                .antMatchers("/file/upload","/video/info/getDetailsById","/video/resource/getSucList"
                        ,"/video/category/getList","/video/hot/list","/video/label/getList","/video/banner/getList").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginProcessingUrl("/admin/sys-user/login").failureHandler(failureHandler).successHandler(successHandler)
                .and()
                .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
        //指定允许跨域的请求(*所有)：http://wap.ivt.guansichou.com
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));
        // setAllowCredentials(true) is important, otherwise:
        // The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
        configuration.setAllowCredentials(true);
        // setAllowedHeaders is important! Without it, OPTIONS preflight request
        // will fail with 403 Invalid CORS request
        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "X-User-Agent", "Content-Type"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}
